home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
glass
/
glass.lha
/
GLASS
/
dtm
/
dtm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-18
|
47KB
|
1,704 lines
/*
File: dtm.c
*/
#include <strings.h>
#include <stdio.h>
#include <tmc.h>
#include <cvr.h>
#include "dtmconst.h"
#include "tmcode.h"
#include "utils.h"
#include "codestorage.h"
#include "typecache.h"
/* command line flags */
static int showorig = TRUE;
static int symtabtr = FALSE;
static int stat = FALSE;
static int utm = 0; /* unit delay model */
static int eich = 0; /* use eichelberger values: 0,x,1 */
static int implicit = 0; /* use implicit clock signals */
/* common variables */
#define infile stdin
#define outfile stdout
FILE *tracestream = stderr;
/* fields of definition to be monitored */
typ intyp, outtyp;
formcon deffc;
val defval;
char **cnames;
typ *ctypes;
int firstsrcnr;
int nrofinputs;
/* names of procs and locals */
#define proclowend 100
int procnr = proclowend;
int localnr = 0;
/*
Table of debugging flags plus associated information.
Table is ended by an entry with flagchar '\0'
*/
static dbflag flagtab[] =
{{ 's', &stat, "statistics" },
{ 't', &symtabtr, "symbol table tracing" },
{ '\0', (int *)0, "" },
};
static void code_generic_zport ();
static void code_generic_uport ();
static void code_generic_mport ();
static void code_dff ();
static void code_jkff ();
static void code_tff ();
static void code_tlatch ();
static void code_tglatch ();
typedef struct
{ char *atomname;
void (*atomcode) ();
char *codedname;
} init_atom;
init_atom known_atoms [] =
{{ "zero", code_generic_zport, "zero" },
{ "one", code_generic_zport, "one" },
{ "undef", code_generic_zport, "undef" },
{ "init", code_generic_zport, "init" },
{ "buf", code_generic_uport, "buf" },
{ "not", code_generic_uport, "not" },
{ "nand", code_generic_mport, "nand2" },
{ "nand2", code_generic_mport, "nand2" },
{ "nand3", code_generic_mport, "nand3" },
{ "nand4", code_generic_mport, "nand4" },
{ "nand5", code_generic_mport, "nand5" },
{ "and", code_generic_mport, "and2" },
{ "and2", code_generic_mport, "and2" },
{ "and3", code_generic_mport, "and3" },
{ "and4", code_generic_mport, "and4" },
{ "and5", code_generic_mport, "and5" },
{ "nor", code_generic_mport, "nor2" },
{ "nor2", code_generic_mport, "nor2" },
{ "nor3", code_generic_mport, "nor3" },
{ "nor4", code_generic_mport, "nor4" },
{ "nor5", code_generic_mport, "nor5" },
{ "or", code_generic_mport, "or2" },
{ "or2", code_generic_mport, "or2" },
{ "or3", code_generic_mport, "or3" },
{ "or4", code_generic_mport, "or4" },
{ "or5", code_generic_mport, "or5" },
{ "xor", code_generic_mport, "xor2" },
{ "xor2", code_generic_mport, "xor2" },
{ "ornot", code_generic_mport, "nand2" },
{ "dff", code_dff, "dff" },
{ "tff", code_tff, "tff" },
{ "jkff", code_jkff, "jkff" },
{ "tlatch",code_tlatch, "tlatch"},
{ "tglatch",code_tglatch, "tglatch"}};
#define nr_of_elts(arr) ((int) (sizeof (arr)/sizeof (arr[0])))
#define streq(s1,s2) (strcmp ((s1),(s2)) == 0)
/*
Die with errormessage
*/
static void Die (s)
char *s;
{ fprintf (stderr, "%s\n", s);
exit (1);
};
/*
Check if we compile for the discrete timing model
*/
static void check_if_dtm ()
{ if (utm)
Die ("This atom can only coded in the discrete timing model\n");
};
/*
Name from symbol.
Because the macroexpander adds _<number> to every symbol
we must remove that suffix when recognizing atoms or source symbols
*/
static char* name_from_symbol (s)
symbol s;
{ char Buf[80];
char *name = symbolstr (s);
int ix;
for (ix = 0; ix < strlen (name) && !(name[ix] == '_'); ix++)
Buf [ix] = name [ix];
Buf [ix] ='\0';
return (new_string (Buf));
};
/*
Create an unique symbol
*/
static int uniquenr = 0;
static symbol unique_name ()
{ char Buf[20];
sprintf (Buf, "gen_'_%d", uniquenr);
uniquenr++;
return (addsymbol (new_string (Buf)));
};
/*
Create a unique val of the given type
*/
static val unique_val_of_type (org, t)
orig org;
typ t;
{ switch (t -> tag)
{ case TAGTypBase:
return (new_VSym (rdup_orig (org), unique_name ()));
case TAGTypProd:
{ register int ix;
typ_list tl = t -> TypProd.ptypes;
val_list nvl = new_val_list ();
room_val_list (nvl, tl -> sz);
nvl -> sz = tl -> sz;
for (ix = 0; ix < tl -> sz; ix++)
nvl -> arr[ix] = unique_val_of_type (org, tl -> arr[ix]);
return (new_VList (nvl));
};
default: badtag (t -> tag);
};
};
/*
Give the formal connection parameters of a def
a procedure nr. We will need it to generate code.
*/
static void prepare1_formcon (fc)
formcon fc;
{ switch (fc -> tag)
{ case TAGFCSym:
{ setprior (fc -> FCSym.sym, procnr);
procnr++;
};
break;
case TAGFCList:
{ register ix;
formcon_list fcl = fc -> FCList.l;
for (ix = 0; ix < fcl -> sz; ix++)
prepare1_formcon (fcl -> arr[ix]);
};
break;
default: badtag (fc -> tag);
};
};
/*
Find the type belonging to each 'fc'. Save also its original
name in the Glass text for user interface purposes.
Do also some consistency checks.
*/
static void prepare2_formcon (fc,t)
formcon fc;
typ t;
{ switch (fc -> tag)
{ case TAGFCSym:
{ symbol sy = fc -> FCSym.sym;
int nr = getprior (sy);
ctypes [nr - proclowend] = rdup_typ (t);
cnames [nr - proclowend] = name_from_symbol (sy);
};
break;
case TAGFCList:
{ formcon_list fcl = fc -> FCList.l;
register int ix;
typ_list tl;
if (t -> tag != TAGTypProd)
Die ("type should be product type");
tl = t -> TypProd.ptypes;
if (fcl -> sz != tl -> sz)
Die ("formcon list and type list should have equal size");
for (ix=0; ix < fcl -> sz; ix++)
prepare2_formcon (fcl -> arr[ix], tl -> arr[ix]);
};
break;
default: badtag (fc -> tag);
};
};
/*
Prepare formal parameters of the definition
*/
static void prepare_formcon (fc, t)
formcon fc;
typ t;
{ int ix;
firstsrcnr = procnr;
prepare1_formcon (fc);
nrofinputs = procnr - firstsrcnr;
cnames = (char **) ckcalloc (procnr, sizeof (char *));
ctypes = (typ*) ckcalloc (procnr, sizeof (typ));
for (ix=0; ix < procnr; ix++) ctypes[ix] = typNIL;
prepare2_formcon (fc, t);
};
/* Given a symbol 's', search the context for a definition with
* that name, and return a pointer to it.
*/
static ctx_list context;
static int symbol_occurs_in (s, v)
symbol s;
val v;
{ switch (v -> tag)
{ case TAGVSym: return (v -> VSym.sym == s);
case TAGVList:
{ val_list vl = v -> VList.l;
register int ix;
for (ix=0; ix < vl -> sz; ix++)
if (symbol_occurs_in (s, vl -> arr[ix])) return (1);
return (0);
};
default: badtag (v -> tag);
};
};
static def find_def (s)
symbol s;
{ register unsigned int cix;
register unsigned int dix;
for (cix = 0; cix < context -> sz; cix++)
{ register def_list l = context -> arr[cix] -> defs;
for (dix = 0; dix < l -> sz; dix++)
{ register def d = l -> arr[dix];
switch (d -> tag)
{ case TAGDefAtom:
if (d -> DefAtom.atnm == s) return (d);
break;
case TAGDefBasetype:
if (d -> DefBasetype.basename == s) return (d);
break;
case TAGDefVal:
if (d -> DefVal.valnm == s) return (d);
break;
case TAGDefTyp:
if (d -> DefTyp.typnm == s) return (d);
break;
case TAGDefCon:
if (symbol_occurs_in (s, d -> DefCon.defcon))
return (d);
break;
case TAGDefConTr:
if (symbol_occurs_in (s, d -> DefConTr.lhs))
return (d);
break;
default:
badtag (d -> tag);
};
};
}
return (defNIL);
};
/* Print usage of this program */
static void usage (f)
FILE *f;
{ fprintf (f, "Usage: dtm [-u] [-i] [-e] [-d<debugging flags>]\n");
fprintf (f, "-i: use implicit clock signals\n");
fprintf (f, "-u: use unit delay model\n");
fprintf (f, "-e: use eichelberger algebra\n");
helpdbflags (f, flagtab);
};
/* scan arguments and options */
static void scanargs (argc, argv)
int argc;
char *argv[];
{ int op;
argv++;
argc--;
while (argc>0)
{ if (argv[0][0] != '-')
{ fprintf (stderr, "too many arguments\n");
usage (stderr);
exit (1);
};
op = argv[0][1];
switch (op)
{ case 'd': setdbflags (&argv[0][2], flagtab, TRUE);
break;
case 'e': eich++;
break;
case 'h':
case 'H': usage (stdout);
exit (0);
case 'i': implicit++;
break;
case 'o': showorig = FALSE;
break;
case 'u': utm++;
break;
default: usage (stderr);
exit (1);
};
argc--;
argv++;
};
};
static def find_thedef (dl)
def_list dl;
{ register int ix;
register def d;
register def mdef = defNIL;
for (ix = 0; ix < dl -> sz; ix++)
{ d = dl -> arr[ix];
if (d -> tag == TAGDefVal)
{ if (mdef == defNIL)
{ mdef = d;
}
else Die ("More than one codible definition found");
};
};
if (mdef == defNIL) Die ("No codible definition found");
return (mdef);
};
/*
value preparation:
The first pass of these rewrites flipflop applications.
The second pass splits where clauses where the left and right hand
side contain equally sized lists.
The third pass replaces DefCon parts by DefConTr parts in the syntax
tree so that the types of where part clauses can be deduced and
code may be generated.
*/
/*
prepare 1 val
rewrites flipflop applications
only the toplevel definitions must be stored on the context list
*/
static val prepare1_val ();
static char *type_error = "This description uses flipflops of the wrong type";
static void check_flipflop_type (atnm, t)
char *atnm;
typ t;
{ check_if_dtm ();
if (eich)
Die ("Eichelberger algebra may not be used for flipflops (yet)");
if (implicit && (streq (atnm, "tlatch") || streq (atnm, "tglatch")))
Die ("These flipflops do not have an implicit clock");
if (streq (atnm, "dff") ||
streq (atnm, "tff") ||
streq (atnm, "tlatch"))
{ if (implicit)
{ if (t -> tag != TAGTypBase) Die (type_error);
}
else
{ if (t -> tag != TAGTypProd) Die (type_error);
if (t -> TypProd.ptypes -> sz != 2) Die (type_error);
};
}
else
{ if (t -> tag != TAGTypProd) Die (type_error);
if (implicit)
{ if (t -> TypProd.ptypes -> sz != 2) Die (type_error);
}
else
{ if (t -> TypProd.ptypes -> sz != 3) Die (type_error);
};
};
};
static val prepare_flipflop_application (v)
val v;
{ orig org = v -> VAtom.atorig;
char *atomname = name_from_symbol (v -> VAtom.atnm);
def d = find_def (v -> VAtom.atnm);
typ atctyp = d -> DefAtom.atctyp;
typ uityp = atctyp -> TypUni.uityp;
typ uotyp = atctyp -> TypUni.uotyp;
val ival = unique_val_of_type (org, uityp);
val oval = unique_val_of_type (org, uotyp);
val natomappl = new_VAtom (rdup_orig (org),
rdup_symbol (v -> VAtom.atnm),
rdup_parval_list (v -> VAtom.atvpar),
rdup_val (ival));
def_list wdefs = new_def_list ();
room_def_list (wdefs, 2);
check_flipflop_type (atomname, uityp);
wdefs -> sz = 2;
wdefs -> arr[0] = new_DefCon (rdup_orig (org), rdup_val (oval),
natomappl);
wdefs -> arr[1] = new_DefCon (rdup_orig (org), ival,
prepare1_val (v -> VAtom.atcpar));
rfre_string (atomname);
return (new_VWhere (wdefs, oval));
};
static val prepare1_val (v)
val v;
{ switch (v -> tag)
{ case TAGVSym: return (rdup_val (v));
case TAGVList:
{ register ix;
val_list vl = v -> VList.l;
val_list nvl = new_val_list ();
room_val_list (nvl, vl -> sz);
nvl -> sz = vl -> sz;
for (ix=0; ix < vl -> sz; ix++)
nvl -> arr [ix] = prepare1_val (vl -> arr[ix]);
return (new_VList (nvl));
};
case TAGVAtom:
{ char *atnm = name_from_symbol (v -> VAtom.atnm);
if (streq (atnm, "jkff") ||
streq (atnm, "tff") ||
streq (atnm, "dff") ||
streq (atnm, "tlatch") ||
streq (atnm, "tglatch"))
{ rfre_string (atnm);
return (prepare_flipflop_application (v));
};
rfre_string (atnm);
return (new_VAtom (rdup_orig (v -> VAtom.atorig),
rdup_symbol (v -> VAtom.atnm),
rdup_parval_list (v -> VAtom.atvpar),
prepare1_val (v -> VAtom.atcpar)));
};
case TAGVWhere:
{ register int ix;
def_list dl = v -> VWhere.wdefs;
def_list ndl = new_def_list ();
room_def_list (ndl, dl -> sz);
ndl -> sz = dl -> sz;
for (ix = 0; ix < dl -> sz; ix++)
{ register def d = dl -> arr [ix];
if (d -> tag != TAGDefCon)
Die ("Only local connections allowed");
ndl -> arr [ix] =
new_DefCon (rdup_orig (d -> DefCon.conorig),
rdup_val (d -> DefCon.defcon),
prepare1_val (d -> DefCon.conas));
};
return (new_VWhere (ndl, prepare1_val (v -> VWhere.wval)));
};
default: badtag (v -> tag);
};
};
/*
prepare 2 val: splits local definitions where left and right hand sides
are equally sized lists
*/
static val prepare2_val ();
static void try_split_vals (ndl, org, lhs, rhs)
def_list ndl;
orig org;
val lhs, rhs;
{ val_list lvl, rvl;
int ix;
if ((lhs -> tag != TAGVList) || (rhs -> tag != TAGVList))
{ app_def_list (ndl, new_DefCon (rdup_orig (org), rdup_val (lhs),
prepare2_val (rhs)));
return;
};
lvl = lhs -> VList.l;
rvl = rhs -> VList.l;
if (lvl -> sz != rvl -> sz)
{ app_def_list (ndl, new_DefCon (rdup_orig (org), rdup_val (lhs),
prepare2_val (rhs)));
return;
};
for (ix = 0; ix < lvl -> sz; ix++)
try_split_vals (ndl, org, lvl -> arr[ix], rvl -> arr[ix]);
};
static val prepare2_val (v)
val v;
{ switch (v -> tag)
{ case TAGVSym: return (rdup_val (v));
case TAGVList:
{ register ix;
val_list vl = v -> VList.l;
val_list nvl = new_val_list ();
room_val_list (nvl, vl -> sz);
nvl -> sz = vl -> sz;
for (ix=0; ix < vl -> sz; ix++)
nvl -> arr [ix] = prepare2_val (vl -> arr[ix]);
return (new_VList (nvl));
};
case TAGVAtom: return (new_VAtom (rdup_orig (v -> VAtom.atorig),
rdup_symbol (v -> VAtom.atnm),
rdup_parval_list (v -> VAtom.atvpar),
prepare2_val (v -> VAtom.atcpar)));
case TAGVWhere:
{ def_list dl = v -> VWhere.wdefs;
def_list ndl = new_def_list ();
int ix;
for (ix = 0; ix < dl -> sz; ix++)
{ def d = dl -> arr[ix];
orig org = d -> DefCon.conorig;
val lhs = d -> DefCon.defcon;
val rhs = d -> DefCon.conas;
try_split_vals (ndl, org, lhs, rhs);
};
return (new_VWhere (ndl, prepare2_val (v -> VWhere.wval)));
};
default: badtag (v -> tag);
};
};
/*
prepare 3 val:
replaces DefCon's in the AST by DefConTr's for administrative purposes
(type deduction and code generation)
*/
static val prepare3_val (v)
val v;
{ switch (v -> tag)
{ case TAGVSym: return (rdup_val (v));
case TAGVWhere:
{ register ix;
def_list ndl = new_def_list ();
def_list dl = v -> VWhere.wdefs;
room_def_list (ndl, dl -> sz);
ndl -> sz = dl -> sz;
for (ix = 0; ix < dl -> sz; ix++)
{ register def d = dl -> arr [ix];
int newprocnr = procnr;
procnr++;
ndl -> arr [ix] =
new_DefConTr (rdup_orig (d -> DefCon.conorig),
rdup_val (d -> DefCon.defcon),
prepare3_val (d -> DefCon.conas),
newprocnr);
};
return (new_VWhere (ndl, prepare3_val (v -> VWhere.wval)));
};
case TAGVList:
{ register ix;
val_list vl = v -> VList.l;
val_list nvl = new_val_list ();
room_val_list (nvl, vl -> sz);
nvl -> sz = vl -> sz;
for (ix=0; ix < vl -> sz; ix++)
nvl -> arr [ix] = prepare3_val (vl -> arr[ix]);
return (new_VList (nvl));
};
case TAGVAtom:
return (new_VAtom (rdup_orig (v -> VAtom.atorig),
rdup_symbol (v -> VAtom.atnm),
rdup_parval_list (v -> VAtom.atvpar),
prepare3_val (v -> VAtom.atcpar)));
case TAGVLambda:
case TAGVSigma:
case TAGVApply:
case TAGVAppset:
case TAGVSyn:
Die ("Only wheres, atom applications, lists and symbols are allowed");
default: badtag (v -> tag);
};
};
/*
prepare types
*/
static typ partial_build_typ (v, s, t)
val v;
symbol s;
typ t;
{ switch (v -> tag)
{ case TAGVSym:
{ if (v -> VSym.sym == s) return (rdup_typ (t));
return (typNIL);
};
case TAGVList:
{ register int ix;
val_list vl = v -> VList.l;
typ_list tl = new_typ_list ();
room_typ_list (tl, vl -> sz);
tl -> sz = vl -> sz;
for (ix=0; ix < vl -> sz; ix++)
tl -> arr[ix] = partial_build_typ (vl -> arr[ix], s, t);
return (new_TypProd (tl));
};
default: badtag (v -> tag);
};
};
/*
Unify types
*/
static typ unify_types (t1,t2)
typ t1,t2;
{ if (t1 == typNIL) return (rdup_typ (t2));
if (t2 == typNIL) return (rdup_typ (t1));
if (t1 -> tag != t2 -> tag) Die ("Can not unify types");
switch (t1 -> tag)
{ case TAGTypBase: return (rdup_typ (t1));
case TAGTypProd:
{ typ_list t1l = t1 -> TypProd.ptypes;
typ_list t2l = t2 -> TypProd.ptypes;
typ_list ntl = new_typ_list ();
register int ix;
if (t1l -> sz != t2l -> sz) Die ("Can not unify types");
room_typ_list (ntl, t1l -> sz);
ntl -> sz = t1l -> sz;
for (ix=0; ix < t1l -> sz; ix++)
ntl -> arr[ix] = unify_types (t1l -> arr[ix],
t2l -> arr[ix]);
return (new_TypProd (ntl));
};
default: badtag (t1 -> tag);
};
};
static void update_type_in_def (d, t)
def d;
typ t;
{ int nr = d -> DefConTr.nr - proclowend;
typ newtyp = unify_types (ctypes [nr], t);
rfre_typ (ctypes [nr]);
ctypes [nr] = newtyp;
};
static typ deduce_types_in_val ();
static void deduce_types_in_def (d)
def d;
{ int nr = d -> DefConTr.nr - proclowend;
typ t = deduce_types_in_val (d -> DefConTr.rhs, ctypes [nr]);
update_type_in_def (d,t);
rfre_typ (t);
};
static typ project_type (t, v, s)
typ t;
val v;
symbol s;
{ if (t == typNIL) return (typNIL);
switch (v -> tag)
{ case TAGVSym:
{ if (v -> VSym.sym == s) return (rdup_typ (t));
return (typNIL);
};
case TAGVList:
{ register int ix;
typ rettyp;
typ_list tl = t -> TypProd.ptypes;
val_list vl = v -> VList.l;
for (ix=0; ix < vl -> sz; ix++)
if ((rettyp = project_type (tl -> arr[ix],
vl -> arr[ix], s)) != typNIL)
return (rettyp);
return (typNIL);
};
default: badtag (v -> tag);
};
};
static typ deduce_types_in_val (v,t)
val v;
typ t;
{ switch (v -> tag)
{ case TAGVSym:
{ symbol sy = v -> VSym.sym;
def d;
int nr = getprior (sy);
if (nr >= firstsrcnr)
return (rdup_typ (ctypes [nr - proclowend]));
if ((d = find_def (sy)) == defNIL)
Die ("definition not found");
if (t != typNIL)
{ typ parttyp = partial_build_typ
(d -> DefConTr.lhs, sy, t);
update_type_in_def (d, parttyp);
rfre_typ (parttyp);
};
nr = d -> DefConTr.nr;
return (project_type (ctypes[nr - proclowend],
d -> DefConTr.lhs, sy));
};
case TAGVList:
{ val_list vl = v -> VList.l;
typ_list gtl = typ_listNIL;
int ix;
typ_list ntl = new_typ_list ();
room_typ_list (ntl, vl -> sz);
ntl -> sz = vl -> sz;
if (t != typNIL)
{ if ((t -> tag != TAGTypProd) ||
(t -> TypProd.ptypes -> sz != vl -> sz))
Die ("Mismatch between type and value");
gtl = rdup_typ_list (t -> TypProd.ptypes);
};
for (ix=0; ix < ntl -> sz; ix++)
ntl -> arr[ix] = deduce_types_in_val (vl -> arr[ix],
(t==typNIL)?typNIL:gtl -> arr[ix]);
rfre_typ_list (gtl);
return (new_TypProd (ntl));
};
case TAGVAtom:
{ symbol atnm = v -> VAtom.atnm;
def d = find_def (atnm);
typ dummy = deduce_types_in_val (v -> VAtom.atcpar,
d -> DefAtom.atctyp -> TypUni.uityp);
rfre_typ (dummy);
return (rdup_typ (d -> DefAtom.atctyp -> TypUni.uotyp));
};
case TAGVWhere:
{ typ dummy, rettyp;
typ srctyp = rdup_typ (t); /* t may be overwritten */
def_list dl = v -> VWhere.wdefs;
int ix;
ins_ctx_list (context, 0, new_ctx (rdup_def_list (dl)));
if (t != typNIL)
dummy = deduce_types_in_val (v -> VWhere.wval, srctyp);
for (ix=0; ix < dl -> sz; ix++)
deduce_types_in_def (dl -> arr[ix]);
rettyp = deduce_types_in_val (v -> VWhere.wval, srctyp);
rfre_typ (dummy);
rfre_typ (srctyp);
del_ctx_list (context, 0);
return (rettyp);
};
default: badtag (v -> tag);
};
};
static void deduce_all_where_types ()
{ typ dummy = deduce_types_in_val (defval, outtyp);
rfre_typ (dummy);
};
static int fully_defined (t)
typ t;
{ switch (t -> tag)
{ case TAGTypBase: return (1);
case TAGTypProd:
{ typ_list tl = t -> TypProd.ptypes;
register int ix;
for (ix=0; ix < tl -> sz; ix++)
if (!fully_defined (tl -> arr[ix]))
return (0);
return (1);
};
default: badtag (t -> tag);
};
};
static void check_if_all_types_defined ()
{ int ix;
for (ix=0; ix < procnr-proclowend; ix++)
if (!fully_defined (ctypes[ix]))
Die ("Not all types could be found");
};
static void add_all_types_to_cache (dl)
def_list dl;
{ int ix;
for (ix = 0; ix < dl -> sz; ix++)
{ def d = dl -> arr [ix];
if (d -> tag == TAGDefAtom)
{ typ t = d -> DefAtom.atctyp;
add_to_cache (t -> TypUni.uityp);
add_to_cache (t -> TypUni.uotyp);
};
};
add_to_cache (intyp);
add_to_cache (outtyp);
for (ix = 0; ix < procnr - proclowend; ix++)
add_to_cache (ctypes [ix]);
};
static void prepare_types (dl)
def_list dl;
{ deduce_all_where_types ();
check_if_all_types_defined ();
add_all_types_to_cache (dl);
}
static void prepare (dl)
def_list dl;
{ def d;
val lambdaexp, pass1val, pass2val;
fprintf (stderr, "dtm: preparing...\n");
d = find_thedef (dl);
lambdaexp = d -> DefVal.valas;
intyp = rdup_typ (d -> DefVal.valtyp -> TypUni.uityp);
outtyp = rdup_typ (d -> DefVal.valtyp -> TypUni.uotyp);
deffc = rdup_formcon (lambdaexp -> VLambda.lpar);
context = new_ctx_list ();
ins_ctx_list (context, 0, new_ctx (rdup_def_list (dl)));
pass1val = prepare1_val (lambdaexp -> VLambda.lval);
pass2val = prepare2_val (pass1val);
rfre_val (pass1val);
defval = prepare3_val (pass2val);
rfre_val (pass2val);
prepare_formcon (deffc, intyp);
prepare_types (dl);
rfre_ctx_list (context);
};
/*
code all the includes of the generated program
*/
static void code_include_header (f)
FILE *f;
{ fprintf (f, "#include <stdio.h>\n");
fprintf (f, "#include <X11/Intrinsic.h>\n");
fprintf (f, "#include <X11/StringDefs.h>\n");
fprintf (f, "#include <X11/cursorfont.h>\n");
fprintf (f, "#include <X11/Xaw/Form.h>\n");
fprintf (f, "#include <X11/Shell.h>\n");
fprintf (f, "#include <X11/Xaw/Paned.h>\n");
fprintf (f, "#include \"XtArgs.h\"\n");
fprintf (f, "#include \"Signalmgr.h\"\n");
fprintf (f, "#include \"Signal.h\"\n");
fprintf (f, "#include \"Command.h\"\n");
fprintf (f, "#include \"Toggle.h\"\n");
fprintf (f, "#include \"%sdtm_atoms.c\"\n", (eich)?"e":"");
fprintf (f, "\n");
};
/*
code initial declarations
*/
static void code_initial_decls (f)
FILE *f;
{ fprintf (f, "#define MaxLen 2000\n");
};
/*
code all forward procedure declarations
*/
static void code_forward_procdec (f)
FILE *f;
{ register int i;
for (i = proclowend; i < procnr; i++)
fprintf (f, "static void p%d ();\n", i);
fprintf (f, "static void sim ();\n\n");
};
/*
generate the declaration of a new local
*/
static int code_new_local (f, t)
FILE *f;
typ t;
{ int nr = localnr;
localnr++;
fprintf (f, "\t ");
code_typ (f, t);
fprintf (f, " l%d;\n", nr);
return (nr);
};
static int code_new_int_local (f)
FILE *f;
{ int nr = localnr;
localnr++;
fprintf (f, "\t int l%d;\n", nr);
return (nr);
};
/*
generate the code to declare the arguments of
a signal procedure and the opening brace
*/
static void code_declareargs (f, t)
FILE *f;
typ t;
{ fprintf (f, " ");
code_typ (f, t);
fprintf (f, " *p;\n int t;\n");
};
/*
generate the tail of a routine
*/
static code_routinetail (f)
FILE *f;
{ fprintf (f, "\t};\n\n");
};
/*
generate the code for the input signal procs
*/
static void code_signal_proc (f, s, t)
FILE *f;
symbol s;
typ t;
{ int nr = getprior (s);
fprintf (f, "/* input '%s' */\n", cnames [nr - proclowend]);
fprintf (f, "static ");
code_typ (f, t);
fprintf (f, " a%d [MaxLen];\n", nr);
fprintf (f, "static void p%d (p,t)\n", nr);
code_declareargs (f, t);
fprintf (f, "\t{ *p = a%d [t];\n", nr);
code_routinetail (f);
};
static void code_source_signals (f, fc, t)
FILE *f;
formcon fc;
typ t;
{ switch (fc -> tag)
{ case TAGFCSym:
code_signal_proc (f, fc -> FCSym.sym, t);
break;
case TAGFCList:
{ formcon_list fcl = fc -> FCList.l;
typ_list tl = t -> TypProd.ptypes;
register int ix;
for (ix=0; ix < fcl -> sz; ix++)
code_source_signals (f, fcl -> arr[ix], tl -> arr[ix]);
};
break;
default: badtag (fc -> tag);
};
};
/*
generate code for the atoms
*/
static void code_generic_zport (f, pnr, atnm, arg, t, ds, delay)
FILE *f;
int pnr;
char *atnm;
val arg;
typ t;
int ds;
int delay;
{ sprintf (line_buffer, "\t l%d = %s (t-%d);", ds, atnm, delay);
save_buffer ();
};
static void code_generic_uport (f, pnr, atnm, arg, t, ds, delay)
FILE *f;
int pnr;
char *atnm;
val arg;
typ t;
int ds;
int delay;
{ char buf [80];
int ix, nr;
if (utm)
{ sprintf (line_buffer, "\t if (t-%d > 0){", delay);
save_buffer ();
};
nr = code_val (f, pnr, arg, t, (utm)?delay+1:delay);
sprintf (line_buffer, "\t l%d = %s (l%d);", ds, atnm, nr);
save_buffer ();
if (utm)
{ sprintf (line_buffer, "\t } else l%d = 0;", ds);
save_buffer ();
};
};
static void code_generic_mport (f, pnr, atnm, arg, t, ds, delay)
FILE *f;
int pnr;
char *atnm;
val arg;
typ t;
int ds;
int delay;
{ char buf [80];
int ix, nr;
typ_list tl = t -> TypProd.ptypes;
if (utm)
{ sprintf (line_buffer, "\t if (t-%d > 0){", delay);
save_buffer ();
};
nr = code_val (f, pnr, arg, t, (utm)?delay+1:delay);
sprintf (line_buffer, "\t l%d = %s (", ds, atnm);
for (ix = 0; ix < tl -> sz; ix++)
{ sprintf (buf, "l%d.f%d%s", nr, ix, (ix==tl->sz-1)?");":", ");
strcat (line_buffer, buf);
};
save_buffer ();
if (utm)
{ sprintf (line_buffer, "\t } else l%d = 0;", ds);
save_buffer ();
};
};
static void code_dff (f, pnr, atnm, arg, t, ds, delay)
FILE *f;
int pnr;
char *atnm;
val arg;
typ t;
int ds;
int delay;
{ sprintf (line_buffer, "\t if (t-%d > 0){", delay);
save_buffer ();
if (implicit)
{ int datanr = code_val (f, pnr, arg, t, delay+1);
sprintf (line_buffer, "\t l%d = l%d;", ds, datanr);
save_buffer ();
}
else /* explicit clock signals */
{ val clock = arg -> VList.l -> arr[0];
val data = arg -> VList.l -> arr[1];
typ clocktyp = t -> TypProd.ptypes -> arr[0];
typ datatyp = t -> TypProd.ptypes -> arr[1];
int cnr, cprevnr, prevqnr, datanr;
cprevnr = code_val (f, pnr, clock, clocktyp, delay+1);
cnr = code_val (f, pnr, clock, clocktyp, delay);
sprintf (line_buffer, "\t if ((l%d == 1) && (l%d == 0)){",
cnr, cprevnr);
save_buffer ();
datanr = code_val (f, pnr, data, datatyp, delay+1);
sprintf (line_buffer, "\t l%d = l%d;", ds, datanr);
save_buffer ();
sprintf (line_buffer, "\t } else {");
save_buffer ();
prevqnr = code_new_int_local (f);
sprintf (line_buffer, "\t p%d (&l%d, t-%d);\n",
pnr, prevqnr, delay+1);
save_buffer ();
sprintf (line_buffer, "\t l%d = l%d; };", ds, prevqnr);
save_buffer ();
};
sprintf (line_buffer, "\t } else l%d = 0;", ds);
save_buffer ();
};
static void code_tff (f, pnr, atnm, arg, t, ds, delay)
FILE *f;
int pnr;
char *atnm;
val arg;
typ t;
int ds;
int delay;
{ char buf [80];
int prevqnr;
sprintf (line_buffer, "\t if (t-%d > 0){", delay);
save_buffer ();
prevqnr = code_new_int_local (f);
sprintf (line_buffer, "\t p%d (&l%d, t-%d);\n",
pnr, prevqnr, delay+1);
save_buffer ();
if (implicit)
{ int tnr = code_val (f, pnr, arg, t, delay+1);
sprintf (line_buffer, "\t l%d = (l%d)?not(l%d):l%d;",
ds, tnr, prevqnr, prevqnr);
save_buffer ();
}
else
{ val clock = arg -> VList.l -> arr [0];
val tinput = arg -> VList.l -> arr [1];
typ clocktyp = t -> TypProd.ptypes -> arr[0];
typ tinputtyp = t -> TypProd.ptypes -> arr [1];
int cprevnr = code_val (f, pnr, clock, clocktyp, delay+1);
int cnr = code_val (f, pnr, clock, clocktyp, delay);
int tnr;
sprintf (line_buffer, "\t if ((l%d == 1) && (l%d == 0)) {",
cprevnr, cnr);
save_buffer ();
tnr = code_val (f, pnr, tinput, tinputtyp, delay+1);
sprintf (line_buffer, "\t l%d = (l%d)?not(l%d):l%d; }",
ds, tnr, prevqnr, prevqnr);
save_buffer ();
sprintf (line_buffer, "\t else l%d = l%d;", ds, prevqnr);
save_buffer ();
};
sprintf (line_buffer, "\t } else l%d = 0;", ds);
save_buffer ();
};
static void code_jkff (f, pnr, atnm, arg, t, ds, delay)
FILE *f;
int pnr;
char *atnm;
val arg;
typ t;
int ds;
int delay;
{ char buf [80];
int ix, prevqnr;
sprintf (line_buffer, "\t if (t-%d > 0){", delay);
save_buffer ();
prevqnr = code_new_int_local (f);
sprintf (line_buffer, "\t p%d (&l%d, t-%d);\n",
pnr, prevqnr, delay+1);
save_buffer ();
if (implicit)
{ int nr = code_val (f, pnr, arg, t, delay+1);
sprintf (line_buffer,
"\t l%d = (l%d == 0)?(l%d.f0):(not(l%d.f1));\n",
ds, prevqnr, nr, nr);
save_buffer ();
}
else
{ val clock = arg -> VList.l -> arr[0];
val jinput = arg -> VList.l -> arr[1];
val kinput = arg -> VList.l -> arr[2];
typ clocktyp = t -> TypProd.ptypes -> arr[0];
typ jtyp = t -> TypProd.ptypes -> arr[1];
typ ktyp = t -> TypProd.ptypes -> arr[2];
int cprevnr = code_val (f, pnr, clock, clocktyp, delay+1);
int cnr = code_val (f, pnr, clock, clocktyp, delay);
int jnr,knr;
sprintf (line_buffer, "\t if ((l%d == 1) && (l%d == 0)) {",
cprevnr, cnr);
save_buffer ();
sprintf (line_buffer, "\t if (l%d == 0) {", prevqnr);
save_buffer ();
jnr = code_val (f, pnr, jinput, jtyp, delay+1);
sprintf (line_buffer, "\t l%d = l%d; }", ds, jnr);
save_buffer ();
sprintf (line_buffer, "\t else {");
save_buffer ();
knr = code_val (f, pnr, kinput, ktyp, delay+1);
sprintf (line_buffer, "\t l%d = not(l%d); }}", ds, knr);
save_buffer ();
sprintf (line_buffer, "\t else l%d = l%d;", ds, prevqnr);
save_buffer ();
};
sprintf (line_buffer, "\t } else l%d = 0;", ds);
save_buffer ();
};
static void code_tlatch (f, pnr, atnm, arg, t, ds, delay)
FILE *f;
int pnr;
char *atnm;
val arg;
typ t;
int ds;
int delay;
{ char buf [80];
int ix, prevqnr, dnr, cnr;
val clock = arg -> VList.l -> arr[0];
val data = arg -> VList.l -> arr[1];
typ clocktyp = t -> TypProd.ptypes -> arr[0];
typ dtyp = t -> TypProd.ptypes -> arr[1];
cnr = code_val (f, pnr, clock, clocktyp, delay);
sprintf (line_buffer, "\t if (l%d == 1){", cnr);
save_buffer ();
dnr = code_val (f, pnr, data, dtyp, delay);
sprintf (line_buffer, "\t l%d = l%d; }", ds, dnr);
save_buffer ();
sprintf (line_buffer, "\t else if (t-%d == 0){", delay);
save_buffer ();
sprintf (line_buffer, "\t l%d = 0; }", ds);
save_buffer ();
sprintf (line_buffer, "\t else {");
save_buffer ();
prevqnr = code_new_int_local (f);
sprintf (line_buffer, "\t p%d (&l%d, t-%d);\n",
pnr, prevqnr, delay+1);
save_buffer ();
sprintf (line_buffer, "\t l%d = l%d; };", ds, prevqnr);
save_buffer ();
};
static void code_tglatch (f, pnr, atnm, arg, t, ds, delay)
FILE *f;
int pnr;
char *atnm;
val arg;
typ t;
int ds;
int delay;
{ char buf [80];
int ix, prevqnr, snr, sbnr, dnr;
val s = arg -> VList.l -> arr[0];
val sbar = arg -> VList.l -> arr[1];
val data = arg -> VList.l -> arr[2];
typ styp = t -> TypProd.ptypes -> arr[0];
typ sbartyp = t -> TypProd.ptypes -> arr[1];
typ dtyp = t -> TypProd.ptypes -> arr[2];
snr = code_val (f, pnr, s, styp, delay);
sbnr = code_val (f, pnr, sbar, sbartyp, delay);
sprintf (line_buffer, "\t if ((l%d == 1) && (l%d == 0)){",
snr, sbnr);
save_buffer ();
dnr = code_val (f, pnr, data, dtyp, delay);
sprintf (line_buffer, "\t l%d = l%d; }", ds, dnr);
save_buffer ();
sprintf (line_buffer, "\t else if ((l%d == 1) || (l%d == 0)){",
snr, sbnr);
save_buffer ();
sprintf (line_buffer,
"\t fprintf (stderr, \"TG illegally clocked\\n\");");
save_buffer ();
sprintf (line_buffer, "\t exit (1); }");
save_buffer ();
sprintf (line_buffer, "\t else if (t-%d == 0){", delay);
save_buffer ();
sprintf (line_buffer, "\t l%d = 0; }", ds);
save_buffer ();
sprintf (line_buffer, "\t else {");
save_buffer ();
prevqnr = code_new_int_local (f);
sprintf (line_buffer, "\t p%d (&l%d, t-%d);\n",
pnr, prevqnr, delay+1);
save_buffer ();
sprintf (line_buffer, "\t l%d = l%d; };", ds, prevqnr);
save_buffer ();
};
/*
generate code to select out of a lhs
*/
static void code_project (v, s, suffix, lnr, l2nr)
val v;
symbol s;
char *suffix;
int lnr, l2nr;
{ switch (v -> tag)
{ case TAGVSym:
if (v -> VSym.sym == s)
{ sprintf (line_buffer, "\t l%d = l%d%s;", l2nr,
lnr, suffix);
save_buffer ();
};
break;
case TAGVList:
{ val_list vl = v -> VList.l;
register int ix;
char SBuf [40];
for (ix = 0; ix < vl -> sz; ix++)
{ sprintf (SBuf, "%s.f%d", suffix, ix);
code_project (vl -> arr[ix], s, SBuf, lnr, l2nr);
};
};
break;
default: badtag (v -> tag);
};
};
/*
generate code for a value
*/
static int code_val (f, pnr, v, t, delay)
FILE *f;
int pnr;
val v;
typ t;
int delay;
{ switch (v -> tag)
{ case TAGVSym:
{ def d;
int locnr;
symbol sy = v -> VSym.sym;
int prnr = getprior (sy);
if (prnr < firstsrcnr)
{ d = find_def (sy);
prnr = d -> DefConTr.nr;
};
locnr = code_new_local (f, ctypes [prnr - proclowend]);
sprintf (line_buffer, "\t p%d (&l%d, t-%d);",
prnr, locnr, delay);
save_buffer ();
if (prnr < firstsrcnr)
{ int loc2nr = code_new_local (f, t);
code_project (d -> DefConTr.lhs, sy, "",
locnr, loc2nr);
return (loc2nr);
};
return (locnr);
};
case TAGVWhere:
{ int locnr;
def_list dl = v -> VWhere.wdefs;
ins_ctx_list (context, 0, new_ctx (rdup_def_list (dl)));
locnr = code_val (f, pnr, v -> VWhere.wval, t, delay);
del_ctx_list (context, 0);
return (locnr);
};
case TAGVList:
{ int nr = code_new_local (f, t);
val_list vl = v -> VList.l;
typ_list tl;
int ix;
if (t -> tag != TAGTypProd) Die ("type/val mismatch");
tl = t -> TypProd.ptypes;
if (vl -> sz != tl -> sz) Die ("size mismatch");
for (ix=0; ix < vl -> sz; ix++)
{ int lnr = code_val (f, pnr, vl -> arr[ix],
tl -> arr[ix], delay);
sprintf (line_buffer, "\t l%d.f%d = l%d;",
nr, ix, lnr);
save_buffer ();
};
return (nr);
};
case TAGVAtom:
{ int ix;
int ds = code_new_local (f, t);
char *atnm = name_from_symbol (v -> VAtom.atnm);
def atdef = find_def (v -> VAtom.atnm);
typ argtyp = atdef -> DefAtom.atctyp -> TypUni.uityp;
for (ix = 0; ix < nr_of_elts (known_atoms); ix++)
if (streq (atnm, known_atoms[ix].atomname))
{ /* nog geen system parameters voor atoms */
known_atoms [ix].atomcode
(f, pnr, known_atoms[ix].codedname,
v -> VAtom.atcpar, argtyp, ds, delay);
fre_string (atnm);
return (ds);
};
fprintf (stderr, "Unknown atom %s\n", atnm);
exit (1);
};
};
};
/*
generate the widget structures
*/
static void estab_widget_struct (f, t)
FILE *f;
typ t;
{ switch (t -> tag)
{ case TAGTypBase:
fprintf (f, "Widget");
break;
case TAGTypProd:
{ typ_list tl = t -> TypProd.ptypes;
int ix;
fprintf (f, "struct {");
for (ix = 0; ix < tl -> sz; ix++)
{ estab_widget_struct (f, tl -> arr[ix]);
fprintf (f, " w%d; ", ix);
};
fprintf (f, "}");
};
break;
default: badtag (t -> tag);
};
};
static void code_widget_structs (f)
FILE *f;
{ int nr;
for (nr = firstsrcnr; nr < procnr; nr++)
{ estab_widget_struct (f, ctypes [nr - proclowend]);
fprintf (f, " ws%d;\n\n", nr);
}
estab_widget_struct (f, outtyp);
fprintf (f, " ows;\n\n");
};
static void code_ini_widget_struct (f, ws, father, name, t, ed)
FILE *f;
char *ws;
char *father;
char *name;
typ t;
int ed;
{ switch (t -> tag)
{ case TAGTypBase:
{ fprintf (f,"\t StartArgs;\n");
fprintf (f,"\t SetArg (XtNradioGroup, button);\n");
fprintf (f,"\t button = XtCreateManagedWidget (\"%s\",\n",
name);
fprintf (f,"\t\ttoggleWidgetClass, %s, UseArgs);\n",
father);
fprintf (f,"\t StartArgs;\n");
fprintf (f,"\t SetArg (XtNlevels, %d);\n", (eich)?3:2);
fprintf (f,"\t SetArg (XtNtimeScale, 5);\n");
fprintf (f,"\t SetArg (XtNtimeDivision, 20);\n");
fprintf (f,"\t SetArg (XtNeditable, %d);\n", ed);
fprintf (f,"\t SetArg (XtNsample, init_sig);\n");
fprintf (f,"\t SetArg (XtNmaxSampleLength, MaxLen);\n");
fprintf (f,"\t SetArg (XtNsampleLength, XtNumber (init_sig));\n");
fprintf (f,"\t %s = XtCreateManagedWidget (\"signal\",\n",
ws);
fprintf (f,"\t\tsignalWidgetClass, %s, UseArgs);\n",
father);
};
break;
case TAGTypProd:
{ typ_list tl = t -> TypProd.ptypes;
int ix;
for (ix=0;ix < tl -> sz; ix++)
{ char Buf[80];
char Name[80];
typ t2 = tl -> arr[ix];
sprintf (Buf, "%s.w%d", ws, ix);
sprintf (Name, "%s.%d", name, ix);
code_ini_widget_struct (f, Buf, father, Name, t2, ed);
};
};
break;
default: badtag (t -> tag);
};
};
static void code_init_widget_structs (f)
FILE *f;
{ int nr;
char wsbuf[10];
fprintf (f, "\t button = NULL;\n");
for (nr = firstsrcnr; nr < procnr; nr++)
{ sprintf (wsbuf, "ws%d", nr);
code_ini_widget_struct (f, wsbuf, "inputs",
cnames [nr-proclowend], ctypes [nr-proclowend], 1);
};
fprintf (f, "\t button = NULL;\n");
code_ini_widget_struct (f, "ows", "outputs", "o", outtyp, 0);
};
/*
generate code for a local definition
*/
static void code_local_definition (f, d)
FILE *f;
def d;
{ int nr = d -> DefConTr.nr;
int locnr;
typ t = ctypes[nr-proclowend];
fprintf (f, "/* local def */\n");
fprintf (f, "static int b%d[MaxLen];\n", nr);
fprintf (f, "static ");
code_typ (f, t);
fprintf (f, " a%d[MaxLen];\n", nr);
fprintf (f, "static void p%d (p, t)\n", nr);
code_declareargs (f, t);
fprintf (f, "\t{\n");
init_codebuffer (f);
sprintf (line_buffer, "\t if (b%d[t]) { *p = a%d[t]; }", nr, nr);
save_buffer ();
sprintf (line_buffer, "\t else{");
save_buffer ();
locnr = code_val (f, nr, d -> DefConTr.rhs, t, 0);
flush_codebuffer (f);
fprintf (f, "\t a%d[t] = l%d;\n", nr, locnr);
fprintf (f, "\t b%d[t] = 1;\n", nr);
fprintf (f, "\t *p = l%d; };\n", locnr);
code_routinetail (f);
};
/*
generate code for the wheres
*/
static void code_wheres (f, v)
FILE *f;
val v;
{ switch (v -> tag)
{ case TAGVSym:
break;
case TAGVList:
{ val_list vl = v -> VList.l;
register int ix;
for (ix=0; ix < vl -> sz; ix++)
code_wheres (f, vl -> arr[ix]);
};
break;
case TAGVAtom:
code_wheres (f, v -> VAtom.atcpar);
break;
case TAGVWhere:
{ int ix;
def_list dl = v -> VWhere.wdefs;
ins_ctx_list (context, 0, new_ctx (rdup_def_list (dl)));
code_wheres (f, v -> VWhere.wval);
for (ix=0; ix < dl -> sz; ix++)
code_wheres (f, dl -> arr[ix] -> DefConTr.rhs);
for (ix=0; ix < dl -> sz; ix++)
code_local_definition (f, dl -> arr[ix]);
del_ctx_list (context, 0);
};
break;
default: badtag (v -> tag);
};
};
/*
generate code for the actual definition
*/
static void code_sim (f)
FILE *f;
{ int nr;
fprintf (f, "static void sim (p,t)\n");
code_declareargs (f, outtyp);
fprintf (f, "\t{\n");
init_codebuffer (f);
nr = code_val (f, 0, defval, outtyp, 0);
flush_codebuffer (f);
fprintf (f, "\t *p = l%d;\n", nr);
code_routinetail (f);
};
/*
generate code to recompute output signals
*/
static void code_connect_widget (f, nr, ws, suffix, t)
FILE *f;
int nr;
char *ws;
char *suffix;
typ t;
{ switch (t -> tag)
{ case TAGTypBase:
{ fprintf (f, "\t StartArgs;\n");
fprintf (f, "\t SetArg (XtNsample, &loc);\n");
fprintf (f, "\t SetArg (XtNsampleLength, &len);\n");
fprintf (f, "\t XtGetValues (%s, UseArgs);\n", ws);
fprintf (f, "\t max = (len<max)?max:len;\n");
fprintf (f, "\t for (i=0; i<MaxLen; i++)\n");
fprintf (f, "\t a%d [i]%s = (i<len)?loc[i]:0;\n",
nr, suffix);
};
break;
case TAGTypProd:
{ typ_list tl = t -> TypProd.ptypes;
int ix;
for (ix=0; ix < tl -> sz; ix++)
{ char wsbuf[40];
char sufbuf[40];
sprintf (wsbuf, "%s.w%d", ws, ix);
sprintf (sufbuf, "%s.f%d", suffix, ix);
code_connect_widget (f, nr, wsbuf, sufbuf,
tl -> arr[ix]);
};
};
break;
default: badtag (t -> tag);
};
};
static void code_connect_output (f, ws, suffix, t)
FILE *f;
char *ws;
char *suffix;
typ t;
{ switch (t -> tag)
{ case TAGTypBase:
{ fprintf (f, "\t for (i=0; i<max; i++)\n");
fprintf (f, "\t outarr[i] = out[i]%s;\n", suffix);
fprintf (f, "\t StartArgs;\n");
fprintf (f, "\t SetArg (XtNsampleLength, max);\n");
fprintf (f, "\t SetArg (XtNsample, outarr);\n");
fprintf (f, "\t XtSetValues (%s, UseArgs);\n", ws);
};
break;
case TAGTypProd:
{ typ_list tl = t -> TypProd.ptypes;
int ix;
for (ix=0; ix < tl -> sz; ix++)
{ char wsbuf[40];
char sufbuf[40];
sprintf (wsbuf, "%s.w%d", ws, ix);
sprintf (sufbuf, "%s.f%d", suffix, ix);
code_connect_output (f, wsbuf, sufbuf, tl -> arr[ix]);
};
};
break;
default: badtag (t -> tag);
};
};
static void code_recompute (f)
FILE *f;
{ int nr, ix;
fprintf (f, "static void ReCompute ()\n");
fprintf (f, "\t{ int *loc;\n");
fprintf (f, "\t int max=0;\n");
fprintf (f, "\t ");
code_typ (f, outtyp);
fprintf (f, " out[MaxLen];\n");
fprintf (f, "\t int outarr[MaxLen];\n");
fprintf (f, "\t int i, len;\n");
for (nr = proclowend; nr < firstsrcnr; nr++)
fprintf (f, "\t for (i=0; i < MaxLen; i++) b%d [i] = 0;\n", nr);
for (nr = firstsrcnr; nr < procnr; nr++)
{ char wsbuf[10];
sprintf (wsbuf, "ws%d", nr);
code_connect_widget (f, nr, wsbuf, "", ctypes[nr-proclowend]);
};
fprintf (f, "\t for (i=0; i<max; i++)\n");
fprintf (f, "\t sim (&out[i], i);\n");
code_connect_output (f, "ows", "", outtyp);
code_routinetail (f);
};
/*
generate the main code
*/
static void code_mainprogram (f)
FILE *f;
{ fprintf (f,"#include \"DtmMain.c\"\n");
code_init_widget_structs (f);
fprintf (f,"\t XtAddCallback (inputs, XtNoriginChanged, ");
fprintf (f,"SignalmgrCallbackSetOrigin, outputs);\n");
fprintf (f,"\t XtAddCallback (outputs, XtNoriginChanged, ");
fprintf (f,"SignalmgrCallbackSetOrigin, inputs);\n");
fprintf (f,"\t XtRealizeWidget (top);\n");
fprintf (f,"\t XtAppMainLoop (MyContext);\n");
code_routinetail (f);
};
/*
code the program
*/
static void code (f, dl)
FILE *f;
{ fprintf (stderr, "dtm: coding...\n");
context = new_ctx_list ();
ins_ctx_list (context, 0, new_ctx (rdup_def_list (dl)));
code_include_header (f);
code_initial_decls (f);
code_cached_types (f);
code_forward_procdec (f);
code_source_signals (f, deffc, intyp);
code_wheres (f, defval);
code_sim (f);
code_widget_structs (f);
code_recompute (f);
code_mainprogram (f);
rfre_ctx_list (context);
};
/*
Load all the definitions
*/
static void load (f, dl)
FILE *f;
def_list *dl;
{ if (fscan_def_list (f, dl))
{ fprintf (stderr, "Read error: (%d): %s\n", tmlineno, tmerrmsg);
exit (1);
};
};
main (argc, argv)
int argc;
char *argv [];
{ def_list all_defs;
initsymbol ();
scanargs (argc, argv);
tmlineno = 1;
load (infile, &all_defs);
prepare (all_defs);
code (outfile, all_defs);
if (stat)
{ int ix;
rfre_def_list (all_defs);
rfre_formcon (deffc);
rfre_val (defval);
rfre_typ (intyp);
rfre_typ (outtyp);
for (ix=0; ix < procnr - proclowend; ix++)
rfre_typ (ctypes[ix]);
flush_cached_types ();
flushsymbol ();
stat_ds (stderr);
stat_string (stderr);
};
}